package com.bangyo.common.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.sothis.util.ObjectUtils;
import org.sothis.util.StringUtils;
import org.sothis.util.random.RandomCodeGenerator;

public class CookieFilter extends AbstractHttpFilter
{
    public CookieFilter()
    {
        super();
        userAgentPermanentCookieName = "uap";
        userAgentPermanentCookieDomain = "127.0.0.1";
        userAgentPermanentCookieMaxAge = Integer.MAX_VALUE;
    }

    private String userAgentPermanentCookieName = null;

    private String userAgentPermanentCookieDomain = null;

    private int userAgentPermanentCookieMaxAge = 0;

    private String sessionIdName = "JSESSIONID";

    private String sessionIdDomain = "127.0.0.1";

    private RandomCodeGenerator userAgentPermanentCookieCodeGenerator = null;

    public void doHttpFilter(HttpServletRequest request,
        HttpServletResponse response, FilterChain chain) throws IOException,
        ServletException
    {
        // doUserAgentPermanentFilter(request, response);
        // doJSessionIdFilter(request, response);

        chain.doFilter(request, response);
    }

    @SuppressWarnings("unused")
    private void doJSessionIdFilter(HttpServletRequest request,
        HttpServletResponse response)
    {

        Cookie[] cookies = request.getCookies();
        Cookie cookie = null;
        if (null!=cookies)
        {
            for (Cookie c:cookies)
            {
                if (c.getName().equalsIgnoreCase(sessionIdName)
                    &&sessionIdDomain.equalsIgnoreCase(c.getDomain()))
                {
                    cookie = c;
                }
            }
        }
        if (null==cookie)
        {
            cookie = new Cookie(sessionIdName, request.getSession().getId());
            cookie.setDomain(sessionIdDomain);
            cookie.setPath("/");
            response.addCookie(cookie);
        }
    }

    @SuppressWarnings("unused")
    private void doUserAgentPermanentFilter(HttpServletRequest request,
        HttpServletResponse response)
    {
        Cookie[] cookies = request.getCookies();
        String seed = StringUtils.concat(request.getHeader("User-Agent"),
            request.getRemoteAddr());

        if (logger.isTraceEnabled())
        {
            logger.trace("seed=["+seed+"].");
        }

        if (null==cookies||0==cookies.length)
        {
            if (logger.isDebugEnabled())
            {
                logger
                    .debug("cookie array from client is null or empty, call initUserAgentPermanentCookie().");
            }
            initUserAgentPermanentCookie(response, seed);
        }
        else
        {
            if (logger.isDebugEnabled())
            {
                logger.debug("cookie array from client has "+cookies.length
                    +" cookies, getUserAgentPermanentCookie().");
            }
            Cookie userAgentPermanentCookie = getUserAgentPermanentCookie(cookies);

            if (null==userAgentPermanentCookie)
            {
                if (logger.isDebugEnabled())
                {
                    logger
                        .debug("userAgentPermanentCookie is not found, call initUserAgentPermanentCookie().");
                }
                initUserAgentPermanentCookie(response, seed);
            }
        }
    }

    private Cookie getUserAgentPermanentCookie(Cookie[] cookies)
    {
        for (int i = 0; i<cookies.length; i++)
        {
            Cookie cookie = cookies[i];
            if (ObjectUtils.equal(userAgentPermanentCookieName, cookie
                .getName()))
            {
                return cookie;
            }
        }
        return null;
    }

    private void initUserAgentPermanentCookie(HttpServletResponse response,
        String seed)
    {
        Cookie userAgentPermanentCookie = new Cookie(
            userAgentPermanentCookieName, userAgentPermanentCookieCodeGenerator
                .generateRandomCode(seed));
        userAgentPermanentCookie.setDomain(userAgentPermanentCookieDomain);
        userAgentPermanentCookie.setMaxAge(userAgentPermanentCookieMaxAge);
        userAgentPermanentCookie.setPath("/");
        response.addCookie(userAgentPermanentCookie);
        if (logger.isTraceEnabled())
        {
            logger.trace("userAgentPermanentCookie is initialized, name=["
                +userAgentPermanentCookieName+"], value=["
                +userAgentPermanentCookie.getValue()+"], domain=["
                +userAgentPermanentCookieDomain+"], maxAge=["
                +userAgentPermanentCookieMaxAge+"], path=["
                +userAgentPermanentCookie.getPath()+"].");
        }
    }

    public void setUserAgentPermanentCookieName(
        String userAgentPermanentCookieName)
    {
        this.userAgentPermanentCookieName = userAgentPermanentCookieName;
    }

    public void setUserAgentPermanentCookieCodeGenerator(
        RandomCodeGenerator userAgentPermanentCookieCodeGenerator)
    {
        this.userAgentPermanentCookieCodeGenerator = userAgentPermanentCookieCodeGenerator;
    }

    public void setUserAgentPermanentCookieDomain(
        String userAgentPermanentCookieDomain)
    {
        this.userAgentPermanentCookieDomain = userAgentPermanentCookieDomain;
    }

    public void setUserAgentPermanentCookieMaxAge(
        int userAgentPermanentCookieMaxAge)
    {
        this.userAgentPermanentCookieMaxAge = userAgentPermanentCookieMaxAge;
    }

    public void setSessionIdName(String sessionIdName)
    {
        this.sessionIdName = sessionIdName;
    }

    public void setSessionIdDomain(String sessionIdDomain)
    {
        this.sessionIdDomain = sessionIdDomain;
    }
}